﻿using Hydrogen.Cmd.Interfaces;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using SConsole = System.Console;

namespace Hydrogen.Cmd.Commands
{
    [CommandFlag("df", "downloadfile")]
    public class DownloadFileCommand : CommandBase
    {
        public static new string Discription => "Download files from url.";
        public override void Invoke(params string[] args)
        {
            List<string> argsList = new List<string>();
            argsList.AddRange(args);
            if (args.Length < 3)
            {
                //SConsole.WriteLine("至少两个参数：文件url，保存位置");
                argsList.Add(Environment.CurrentDirectory);
                //return;
            }
            else if ("this".Equals(args[args.Length - 1]))
            {
                argsList.Add(Environment.CurrentDirectory);
            }

            List<string> urls = new List<string>();
            for (int i = 1; i < argsList.Count - 1; i++)
            {
                urls.Add(argsList[i]);
            }
            string targetDir = argsList[argsList.Count - 1];

            Parallel.ForEach(urls, url => GetImage(url, targetDir));
            timeoutList.AddRange(tempTimeoutList);
            while (timeoutList.Count > 0)
            {
                timeoutList.Clear();
                timeoutList.AddRange(tempTimeoutList);
                tempTimeoutList.Clear();
                SConsole.ForegroundColor = ConsoleColor.Red;
                SConsole.WriteLine("超时补全，剩余：" + timeoutList.Count);
                SConsole.ForegroundColor = ConsoleColor.White;
                Parallel.ForEach(timeoutList, url => GetImage(url, targetDir));
            }
            SConsole.WriteLine(">> 完成");
        }

        static object lockObj = new object();
        static List<string> timeoutList = new List<string>();
        static List<string> tempTimeoutList = new List<string>();

        private static void GetImage(string url, string dirName)
        {
            string targetFile = Path.Combine(dirName, Path.GetFileName(url));
            if (File.Exists(targetFile))
            {
                File.Delete(targetFile);
            }
            SConsole.WriteLine("准备下载至：" + targetFile);
            //string targetUrl = "https://static4.hentai-img.com/upload/20170422/283/289742/" + i + ".jpg";
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44";
            try
            {
                WebResponse response = request.GetResponse();
                using (Stream stream = response.GetResponseStream())
                {
                    using (FileStream fs = new FileStream(targetFile, FileMode.OpenOrCreate, FileAccess.Write))
                    {
                        int readCountPre = 1024;
                        int readedCount = readCountPre;
                        byte[] buffer = new byte[readCountPre];

                        while (readedCount > 0)
                        {
                            readedCount = stream.Read(buffer, 0, readCountPre);
                            fs.Write(buffer, 0, readedCount);
                        }
                    }
                }
                lock (lockObj)
                {
                    SConsole.WriteLine("完成 {0}", url);
                }
            }
            catch (WebException e)
            {
                SConsole.WriteLine("[{0}] --> {1}", url, e);
                if (e.Status == WebExceptionStatus.Timeout)
                {
                    lock (tempTimeoutList)
                    {
                        if (!tempTimeoutList.Contains(url)) tempTimeoutList.Add(url);
                    }
                }
                return;
            }
            catch (Exception e)
            {
                SConsole.WriteLine("[{0}] --> {1}", url, e);
            }

        }
    }
}
